<?php

abstract class AbstractTableRecord {

	/**
	 * @return AbstractTableAccessor
	 */
	abstract public function getAccessor();

	protected $key;
	public function getKey() { return $this->key; }

	protected $hValues;
	public function getHash() { return $this->hValues; }

	public function __construct($key = null) {
		$this->key = $key;
	}

	public function updateFromHash(array $hValues) {
		foreach ($hValues as $fieldName => $value) {
			$this->setField($fieldName, $value);
		}
	}

	protected function getField($fieldName) {
		$this->getAccessor()->checkFieldExists($fieldName);
		return isset($this->hValues[$fieldName]) ?
			$this->hValues[$fieldName] :
			'';
	}

	protected function setBoolField($fieldName, $value) {
	   $this->setField($fieldName, intval((bool)$value));
	}

	protected function setDateTimeField($fieldName, Date $oDate) {
	   $this->setField($fieldName, $oDate->sqlFormat());
	}

	/**
	 * @return Date
	 */
	protected function getDateTimeField($fieldName) {
	   return Date::createFromSqlFormat($this->getField($fieldName));
	}

	protected function setField($fieldName, $value) {

	    if (Settings::config('system')->get('debug', 'is_db_strict')) {
            $this->getAccessor()->checkFieldExists($fieldName);
	    }
		$this->hValues[$fieldName] = $value;
	}

	abstract protected function checkFieldsBeforeSave();

	final public function save() {

	    if ($this->isDeleted)
	       throw new Exception('Cannot save deleted record');

		$this->checkFieldsBeforeSave();
        //Debug::show('$this->hValues',$this->hValues);
		if ($this->key === null) {

			$oInserted = $this->getAccessor()->insertRecord($this);
            $this->updateFromHash($oInserted->getHash());
            $this->key = $oInserted->getKey();

		} else {
			$this->getAccessor()->updateRecord($this);
		}

		return $this->key;
	}

	private $isDeleted = false;
	final public function delete() {
        $this->getAccessor()->deleteRecordByKeyField($this->getKey());
        $this->isDeleted = true;
	}
}

?>